package com.fiveGroup.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fiveGroup.pojo.AdminUser;
import com.fiveGroup.pojo.User;
import com.fiveGroup.pojo.vo.ChangePasswordDto;
import com.fiveGroup.pojo.vo.DataVo;
import com.fiveGroup.pojo.vo.LoginVo;
import com.fiveGroup.service.AdminUserService;
import com.fiveGroup.service.UserService;
import com.fiveGroup.util.JwtUtil;
import com.fiveGroup.util.UserContextHolder;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;


@RestController
@RequiredArgsConstructor//构造注入
@Slf4j
@RequestMapping("/api/user")
public class UserController {

    private final UserService service;
    private final AdminUserService adminUserService;

    private final JwtUtil jwtUtil;

    private final PasswordEncoder passwordEncoder;



    @PostMapping("/login")
    public DataVo login(@RequestBody LoginVo loginVo) {
        //先判断用户身份
        String role = loginVo.getRole();
        if (role.equals("admin")) {
            LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AdminUser::getUsername, loginVo.getUsername());
            AdminUser userbyDb = adminUserService.getOne(queryWrapper);
            if (userbyDb == null) {
                return DataVo.fail("用户不存在");
            }
            String password = loginVo.getPassword();
//        checkpw检查原文密码与加密密码是否一致
            boolean checkpw = BCrypt.checkpw(password, userbyDb.getPassword());
            if (checkpw) {
                //3.验证账号密码成功 下发一个JWT Token
                HashMap<String, Object> map = new HashMap<>();
                map.put("loginTime", System.currentTimeMillis());
                map.put("username", userbyDb.getUsername());
                map.put("userId", userbyDb.getId());
                map.put("userType", "admin");//添加登录管理的类型
                String token = jwtUtil.createToken(map, userbyDb.getUsername());
                return DataVo.success(token);
            }
            return DataVo.fail("账号或密码错误");
        } else if (role.equals("user")) {
            //1.查询用户是否存在
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, loginVo.getUsername());
            User userbyDb = service.getOne(queryWrapper);
            if (userbyDb == null) {
                return DataVo.fail("用户不存在");
            }
            if (userbyDb.getStatus() == 1) return DataVo.fail("该账号被封禁");
            String password = loginVo.getPassword();
//        checkpw检查原文密码与加密密码是否一致
            boolean checkpw = BCrypt.checkpw(password, userbyDb.getPassword());
            if (checkpw) {
                //3.验证账号密码成功 下发一个JWT Token

                HashMap<String, Object> map = new HashMap<>();
                map.put("loginTime", System.currentTimeMillis());
                map.put("username", userbyDb.getUsername());
                map.put("userId", userbyDb.getId());
                map.put("userType", "user");//添加登录用户的类型
                String token = jwtUtil.createToken(map, userbyDb.getUsername());
                return DataVo.success(token);
            }
            return DataVo.fail("账号或密码错误");
        } else {
            return DataVo.fail("出现错误");
        }
    }

    //注册
    @PostMapping("/register")
    public DataVo register(@RequestBody User user) {
        //1.查询用户是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, user.getUsername());
        User userbyDb = service.getOne(queryWrapper);
        if (userbyDb != null) return DataVo.fail("用户已存在");
        //将密码加密
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        //注册账号
        boolean save = service.save(user);
        return save ? DataVo.success("成功注册") : DataVo.fail("注册失败");
    }

    //注销用户(隐式删除)
    @PostMapping("/deleteUser")
    public DataVo deleteUser(@RequestBody Map<String, Long> map) {
        Long userId = map.get("userId");
        //获取当前登录用户的id
        if (!userId.equals(UserContextHolder.getUserId())) return DataVo.fail("非法操作");
        //注销
        boolean b = service.removeById(userId);
        return b ? DataVo.success(userId) : DataVo.fail("删除失败");
    }

    //    获取当前页面用户信息
    @GetMapping("/userMessage")
    public DataVo userMessage(@RequestHeader(value = "token") String token) {
        Claims claims = jwtUtil.extractAllClaims(token);
        Integer userId = (Integer) claims.get("userId");
        User byId = service.getById(userId);
        return DataVo.success(byId);
    }

    //获取用户头像和用户名
    @GetMapping("/getUserInfo")
    public DataVo getUserInfo(@RequestHeader(value = "token") String token) {
        try {
            // 检查token是否存在
            if (token == null || token.isEmpty()) {
                return DataVo.fail("用户未登录");
            }
            //从token中提取用户信息
            Claims claims = jwtUtil.extractAllClaims(token);
            log.info(claims.toString());
            //从claims中提取用户id
            Integer userIdInteger = (Integer) claims.get("userId");
            if (userIdInteger == null) {
                return DataVo.fail("用户未登录");
            }
            Long userId = Long.valueOf(userIdInteger);
            //与上下文id对比,确保是本人操作
            System.out.println(userId);
            System.out.println(UserContextHolder.getUserId());
            if (!userId.equals(UserContextHolder.getUserId())) {
                return DataVo.fail("非法操作");
            }
            //根据用户id查询用户信息
            User byId = service.getById(userId);
            if (byId != null) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("username", byId.getUsername());
                map.put("avatar", byId.getAvatar());
                log.info("用户{}获取头像和用户名", map);
                return DataVo.success(map);
            } else {
                return DataVo.fail("用户不存在");
            }
        } catch (Exception e) {
            return DataVo.fail("获取用户信息失败");
        }
    }

    //修改g个人信息
    @PostMapping("/updateById")
    public DataVo updateById(@RequestBody User user) {
        //先判断是否为本人操作
        Long userId = user.getId();
        if (!userId.equals(UserContextHolder.getUserId())) {
            return DataVo.fail("非法操作");
        }
        boolean b = service.updateById(user);
        return b ? DataVo.success(user) : DataVo.fail("修改失败");
    }

    //修改密码
    @PostMapping("/changePassword")
    public DataVo changePassword(@RequestBody ChangePasswordDto dto) {
        // 1. 根据用户名查询用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, dto.getUsername());
        User user = service.getOne(queryWrapper);

        if (user == null) {
            return DataVo.fail("用户不存在");
        }
        //判断是否是本人操作
        Long userId = user.getId();
        if (!userId.equals(UserContextHolder.getUserId())) {
            return DataVo.fail("非法操作");
        }
        // 2. 验证原密码
        if (!passwordEncoder.matches(dto.getOldPassword(), user.getPassword())) {
            return DataVo.fail("原密码错误");
        }
        // 3. 加密新密码并更新
        user.setPassword(passwordEncoder.encode(dto.getNewPassword()));
        boolean success = service.updateById(user);

        return success ? DataVo.success("密码修改成功") : DataVo.fail("密码修改失败");
    }



}
